from PyPixelCore.Setting import *
from PyPixelCore.block.Block import Block
from PyPixelCore.timer.CycleTimer import CycleTimer
from PyPixelCore.util.filer import *


def base_draw(self, surf):
    if self.now_image_state:
        surf.blit(self.now_image_arr[self.now_frame_index], self.rect)
    if show_rect_collision and self.now_image_state is not None:
        img_rect = self.now_image_arr[self.now_frame_index].get_rect()
        pygame.draw.rect(surf, Color_type.BRIGHT_BLUE, img_rect, width=image_surface_width)
        pygame.draw.rect(surf, Color_type.RED, self.rect, width=block_surface_width)
        pygame.draw.rect(surf, Color_type.BLACK, self.collision_rect, width=collision_surface_width)


"""
    DynamicImageBlock --> Block --> BaseBlock
    动态图片块
    
     功能:
        显示图像或者自定义绘制图像
        支持碰撞检测
        支持帧函数与计时器函数
        支持公共计时器绘制
    
    # 重点: 多种图片获取加载技术
    加载1: 被动接受已经整理完毕的状态字典
    加载2: 被动接受已经整理完毕的某个状态的播片列表
    加载3: 自动加载已经整理完毕的文件夹包裹的图片组
    加载4: 自动按要求切割图片并加载
"""


class DynamicImageBlock(Block):
    def __init__(self, width=100, height=100, bk_color=Color_type.BLACK, point_x=0, point_y=0, layer=0, collision=False, is_alpha=False):
        super().__init__(width, height, bk_color, point_x, point_y, layer, collision, is_alpha)
        self.draw_func = base_draw
        self.image_dict = {}  # 用于不同状态下的播片
        self.now_image_arr = []  # 当前播片列表
        self.now_frame_index = 0  # 当前播片位置
        self.now_image_state = None
        self.max_frame_index = 0  # 最大播片值
        self.animation_interval = 16  # 播放动画间隔帧
        self._type = Block_type.dynamic_image_block
        self.collision_rect = self.rect.copy()

        # 第一个位置是播放动画的计时器(专属)     ([animation_timer, update_image_index],[some, some],[some, some],[some, some]...)
        self.timer_arr.append([CycleTimer(self.animation_interval), self.update_image_index])

    # def draw(self, surf):

    def update_image_index(self, _):
        # 更新动画帧
        if self.max_frame_index == 0:
            return
        if self.now_frame_index == self.max_frame_index:
            self.now_frame_index = 0
        else:
            self.now_frame_index += 1
        self.is_dirty = True

    def set_video_state(self, state_name):
        # 改变当前播片动画的图片组
        if state_name in self.image_dict.keys():
            self.now_image_state = state_name
            self.now_image_arr = self.image_dict[state_name]
            self.now_frame_index = 0
            self.max_frame_index = len(self.now_image_arr) - 1

    def set_animation_interval(self, interval):
        # 设置当前动画的计时器动画帧
        self.animation_interval = interval
        self.timer_arr[0][0] = CycleTimer(interval)  # 更新计时器

    def set_image_dict(self, finish_dict, limit=True):
        # 加载1: 被动接受已经整理完毕的状态字典
        if limit:
            finish_dict = self.limit_image_size(finish_dict)
        self.image_dict = finish_dict

    def add_imageArr_to_dict(self, image_arr, state_name, limit=True):
        # 加载2: 被动接受已经整理完毕的某个状态的播片列表
        if limit:
            image_arr = self.limit_image_size(image_arr)
        self.image_dict[state_name] = image_arr

    def set_image_dict_from_file(self, path, limit=True):
        # 加载3: 自动加载已经整理完毕的文件夹包裹的图片组完整
        aim_dict = import_folder_dict(path)
        if limit:
            aim_dict = self.limit_image_size(aim_dict)
        self.image_dict = aim_dict

    def add_image_list_from_file(self, path, state_name, limit=True):
        # 加载3: 自动加载已经整理完毕的文件夹包裹的图片组非完整
        aim_array = import_folder(path)
        if limit:
            aim_array = self.limit_image_size(aim_array)
        self.image_dict[state_name] = aim_array

    def add_image_list_from_image(self, path, name, w_num=1, h_num=1, start_line=1, end_line=None, limit=True):
        # 加载4: 自动按要求切割图片
        if end_line is None:
            end_line = start_line
        sub_images = []
        original_image = pygame.image.load(path).convert_alpha()
        # 计算每个子图像的宽度和高度
        w_size = original_image.get_width() // w_num  # 使用整除来确保结果为整数
        h_size = original_image.get_height() // h_num  # 正确的使用原始图像的高度
        # 执行切割
        for j in range(start_line - 1, end_line):  # 纵向遍历（行）
            for i in range(w_num):  # 横向遍历（列）
                # 裁剪子图像
                # 注意：subsurface的参数是(x, y, width, height)
                sub_image = original_image.subsurface((i * w_size, j * h_size, w_size, h_size))
                sub_images.append(sub_image)
        # 根据需求限制图形大小
        if limit:
            sub_images = self.limit_image_size(sub_images)
        # 将动画播片放入字典存储
        self.image_dict[name] = sub_images

    def add_image_list_from_images(self, path, name_arr, w_num, h_num, limit=True):  # 没有优化,直接调用的函数
        # 加载4: 自动按要求切割图片整体
        line = 0
        for name in name_arr:
            line += 1
            self.add_image_list_from_image(path, name, w_num, h_num, line, limit=limit)

    def limit_image_size(self, dict_or_array):  # 限制图像大小
        if isinstance(dict_or_array, dict):
            # 限制字典
            for values in dict_or_array.values():
                for i, value in enumerate(values):  # 使用 enumerate 获取索引和值
                    # 直接通过索引修改列表中的元素
                    values[i] = pygame.transform.scale(value, (self.rect.width, self.rect.height))
        else:
            # 限制数组
            for i, value in enumerate(dict_or_array):  # 使用 enumerate 获取索引和值
                # 直接通过索引修改列表中的元素
                dict_or_array[i] = pygame.transform.scale(value, (self.rect.width, self.rect.height))
        return dict_or_array


